package com.donglink.test.logmonitor.dao;

import com.donglink.test.logmonitor.entry.App;
import com.donglink.test.logmonitor.entry.Message;
import com.donglink.test.logmonitor.entry.Rule;
import com.donglink.test.logmonitor.entry.User;
import com.donglink.test.logmonitor.service.impl.FilterServiceImpl;
import org.apache.ibatis.io.ResolverUtil;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class MybatisDriver {

    //变量作用域，深拷贝浅拷贝，
     static List<Rule> rules;;
    private static  boolean reload;
    static Map<Integer,User> userMap;
    //存放所有需要进行过滤的app
    public static Map<Integer, App> appMap;
    //所有监控到的app对象
//    private static Map<Integer,List<Rule>> appListMap;
    public static SqlSessionFactory sqlSessionFactory;
    public static void init(){
        //初始化变量
        rules=new ArrayList<>();
        userMap=new HashMap<>();
        appMap=new HashMap<>();

        String resource = "mybatis-config.xml";
        InputStream inputStream = null;
        try {
            inputStream = Resources.getResourceAsStream(resource);
        } catch (IOException e) {
            e.printStackTrace();
        }
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        reload=true;
        rwl.writeLock().lock();
        getdata();
        rwl.writeLock().unlock();

    }

    //从mysql拉取app过滤信息并放到map中
    private static void pullAppMap()
    {
        List<App> apps=null;
        try (SqlSession session = sqlSessionFactory.openSession()) {
            AppMapper mapper = session.getMapper(AppMapper.class);
            apps = mapper.selectAllUsedApp();
        }
        appMap.clear();
        for (App app:apps)
        {
            appMap.put(app.getAppId(),app);
        }
    }



    //每两分钟更新一次数据库数据到本地
    public static  void pullAllData() {
        Date date = new Date();
        SimpleDateFormat dateFormat= new SimpleDateFormat("mm");
        int m=Integer.parseInt(dateFormat.format(date));
        if(m%2==0){
            rwl.writeLock().lock();
            getdata();
            rwl.writeLock().unlock();
//            System.out.println(appMap);
//            System.out.println(userMap);
//            System.out.println(rules);
        }else

        {
            reload=true;
        }


    }
    private static  void pullRules()
    {

        List<Rule> tmp;
        rules.clear();
        try (SqlSession session = sqlSessionFactory.openSession()) {
            RuleMapper mapper = session.getMapper(RuleMapper.class);
            tmp=mapper.selectAll();

            for (Rule rule:tmp)
            {
                rules.add(rule);
            }
        }

    }




    private static synchronized void getdata() {
        if(reload)
        {
            //loaddata

            pullAppMap();
            pullRules();
            pullUserMap();
//            System.out.println(appMap);
//            System.out.println(userMap);
            System.out.println("重新加载mysql规则数据成功");
            reload=false;
        }

    }

    private static void pullUserMap()
    {
        userMap.clear();
        try (SqlSession session = sqlSessionFactory.openSession()) {
            UserMapper mapper = session.getMapper(UserMapper.class);
            List<User> users= mapper.selectAll();
            for (User user:users)
            {
                userMap.put(user.getUserId(),user);
            }

        }
    }


    static ReadWriteLock rwl = new ReentrantReadWriteLock();

    public static List<Message> proccess(String log, App app) {


        List<Message> messages=new ArrayList<>();
        rwl.readLock().lock();
        for (Rule rule:rules)
        {
            if(log.contains(new StringBuffer(rule.getGuize())))
            {
                String mail=userMap.get(rule.getUserId()).getUserMail();


                if(mail!=null)
                {
                    messages.add(new Message(log,mail));
                }
                else
                {
                    messages.add(new Message(log,"964158490@qq.com"));
                }

            }
        }
        rwl.readLock().unlock();
        return  messages;
    }

    public static App isUnqualified(String log) {

        //进行日志判断，是否需要过滤，没有数据库中规定的appid就直接过滤掉
        String appid=log.split("\\$\\$\\$\\$\\$")[0];
        rwl.readLock().lock();
        App app=MybatisDriver.appMap.get(Integer.parseInt(appid));
        rwl.readLock().unlock();
        return app;
    }
}
